package com.artieksi.core;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import twitter4j.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Properties;

/**
 * User: TTACANSEVER
 */
public class Application {

    private static ClassPathXmlApplicationContext APPLICATION_CONTEXT;
    private static JdbcTemplate jdbcTemplate;
    private static TwitterStream twitterStream;
    private static Twitter twitter;
    private static Properties props;

    private static final String signSql = " insert into signs (signer_id, signed_id, signer_username, signed_username, sign, sign_time, latitude, longitude, picture_url) " +
                                          " values(?, ?, ?, ?, ?, ?, ? ,?, ?)";

    public static void main(String[] args) throws IOException {

        readProperties();
        APPLICATION_CONTEXT = new ClassPathXmlApplicationContext(new String[]{"application.xml"});
        jdbcTemplate = (JdbcTemplate) APPLICATION_CONTEXT.getBean("jdbcTemplate");
        twitter = new TwitterFactory().getInstance();

        final String streamUserName = (String) props.get("twitter.user.name");

        UserStreamListener listener = new UserStreamListener() {
            @Override
            public void onStatus(Status status) {
                try {
                    int streamUsernameIndex = 0;
                    String[] words = status.getText().split("\\s+");
                    if (words.length >= 3) {
                        for(int i = 0; i < words.length; i++) {
                            String word = words[i];
                            if(streamUserName.equalsIgnoreCase(word.replaceAll("@", ""))) {
                                streamUsernameIndex = i;
                                break;
                            }
                        }

                        if(streamUsernameIndex >= 2) {
                            String signedUserName = words[streamUsernameIndex - 2].replace("@", "");
                            String sign = words[streamUsernameIndex - 1];
                            User signedUser = twitter.showUser(signedUserName);
                            if (signedUser != null && ("+".equals(sign) || "-".equals(sign))) {
                                long signedUserId = signedUser.getId();
                                DbSignObject signObject = new DbSignObject();
                                signObject.setSignerId(status.getUser().getId());
                                signObject.setSignedId(signedUserId);
                                signObject.setSignerUsername(status.getUser().getScreenName());
                                signObject.setSignedUsername(signedUserName);
                                signObject.setSign(sign);
                                signObject.setSignTime(new Timestamp(status.getCreatedAt().getTime()));
                                signObject.setPictureUrl(signedUser.getProfileImageURL());
                                if (status.getGeoLocation() != null) {
                                    signObject.setLatitude(status.getGeoLocation().getLatitude());
                                    signObject.setLongitude(status.getGeoLocation().getLongitude());
                                } else {
                                    signObject.setLatitude(0);
                                    signObject.setLongitude(0);
                                }
                                insertSign(signObject);
                            }
                        }
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            public void onDeletionNotice(long l, long l2) { }
            public void onFriendList(long[] longs) { }
            public void onFavorite(User user, User user2, Status status) { }
            public void onUnfavorite(User user, User user2, Status status) { }
            public void onFollow(User user, User user2) { }
            public void onDirectMessage(DirectMessage directMessage) { }
            public void onUserListMemberAddition(User user, User user2, UserList userList) { }
            public void onUserListMemberDeletion(User user, User user2, UserList userList) { }
            public void onUserListSubscription(User user, User user2, UserList userList) { }
            public void onUserListUnsubscription(User user, User user2, UserList userList) { }
            public void onUserListCreation(User user, UserList userList) { }
            public void onUserListUpdate(User user, UserList userList) { }
            public void onUserListDeletion(User user, UserList userList) { }
            public void onUserProfileUpdate(User user) { }
            public void onBlock(User user, User user2) { }
            public void onUnblock(User user, User user2) {}
            public void onDeletionNotice(StatusDeletionNotice statusDeletionNotice) { }
            public void onTrackLimitationNotice(int i) { }
            public void onScrubGeo(long l, long l2) {}
            public void onStallWarning(StallWarning stallWarning) { }
            public void onException(Exception e) { }
        };

        TwitterStream twitterStream = new TwitterStreamFactory().getInstance();
        twitterStream.addListener(listener);
        twitterStream.user();

    }

    public static void readProperties() throws IOException {
        InputStream inputStream = Application.class.getClassLoader().getResourceAsStream("arti-eksi-core.properties");
        props = new Properties();
        props.load(inputStream);
        inputStream.close();
    }

    private static void insertSign(DbSignObject object) throws SQLException {
        jdbcTemplate.update(signSql,
                            object.getSignerId(),
                            object.getSignedId(),
                            object.getSignerUsername(),
                            object.getSignedUsername(),
                            object.getSign(),
                            object.getSignTime(),
                            object.getLatitude(),
                            object.getLongitude(),
                            object.getPictureUrl());
    }
}
